/** 
 * @file output.c
 * @brief output static
 * @author Red Li
 * @version 1.0.0
 * @date 2009-08-16
 */


#include "utils.h"
#include "output.h"
#include <signal.h>
#include <sys/time.h>


static const char *statis_class[] =
{
	"query",
	"auth-query",
	"acct-query",
	"trans",
	"auth-trans",
	"acct-trans",
	"session",
	"othertype",
	NULL
};

static const char *statis_type[] =
{
	"sent",
	"resent",
	"completed",
	"accepted",
	"reject",
	"detectlost",
	"timeout",
	NULL
};

unsigned int statis[CLASS_END][TYPE_END];
extern utime_t statis_start;
extern utime_t time_out;


//!< 
extern int count_per;
extern int busy_pkt;
extern int timeout_decrease;
extern int count_decrease;


/* --------------------------------------------------------------------------*/
/** 
 * @brief for statis clients state
 * 
 * @review draft
 */
/* ----------------------------------------------------------------------------*/
int state_count[CLIENT_TOTAL + 1];



//!< resources of sock with radius id[0-255]
resources_t *resource = NULL;		
//!< size of resource
int num_resource = 0;

static int output_enable = 0;

int output_init(int sec)
{
#ifdef CURSES
	initscr();	
	refresh();
	output_enable = sec;
	signal(SIGALRM, output_refresh);
	alarm(output_enable);
#else
	//system("clear");
#endif
	return 1;
	
}


void output_refresh(int sig)
{
#ifdef CURSES
	static ori_max_x, ori_max_y;
	int max_x, max_y;
	int x, y = 0;
	int step;
	int i, j;

#ifdef CLIENT
	getmaxyx(stdscr, max_y, max_x);
	step = max_x / (TYPE_END + 2);
	x = y = 0;
	if(ori_max_x != max_x || ori_max_y != max_y)
	{
		ori_max_x = max_x;
		ori_max_y = max_y;
		clear();
	}
	mvprintw(y, x, "<class> ");
	
	for(i = 0; i < TYPE_END; i++)
	{
		x += step;
		mvprintw(y, x, "<%s>", statis_type[i]);
	}
	x+= step;
	mvprintw(y, x, "<QPS>");

	for(j = 0; j < CLIENT_END; j++)
	{
		x = 0;
		y++;
		mvprintw(y, x, "%s", statis_class[j]);
		for(i = 0; i < TYPE_END; i++)
		{
			x += step;
			mvprintw(y, x, "  %d", statis[j][i]);
		}
		x += step;
		mvprintw(y, x, "  %.3f", (float)statis[j][COMPLETED] / ((float)(get_time() - statis_start) / TIME_GAP)); 
	}

	y++;
	mvprintw(y, 0, "client:%d idle:%d busy:%d dead:%d num_resource:%d time_ecapse:%.3f time_out:%d ms\ncount_per:%d count_decrease:%d busy_pkt:%d timeout_decrease:%d \n", 
				state_count[CLIENT_TOTAL],
				state_count[CLIENT_IDLE],
				state_count[CLIENT_BUSY],
				state_count[CLIENT_DEAD],
				num_resource, 
				(get_time() - statis_start) / (TIME_GAP * 1.0),
				time_out / (TIME_GAP / 1000),
                count_per,
                count_decrease,
                busy_pkt,
                timeout_decrease
                );
#endif

#ifdef SERVER
	y++;
    static int former_pkts = 0;
	mvprintw(y + 1, 0, "server total recv:%d total drop:%d total auth recv:%d total auth reject:%d pkts/s:%d \n",
			statis[_SERVER][TOTAL_PKTS],
			statis[_SERVER][TOTAL_LOST],
			statis[_SERVER][TOTAL_AUTH],
			statis[_SERVER][TOTAL_REJECT],
            statis[_SERVER][TOTAL_PKTS] - former_pkts);
    former_pkts = statis[_SERVER][TOTAL_PKTS];
#endif

	refresh();
	alarm(output_enable);

#else

#endif
}



void output_close()
{
#ifdef CURSES
	output_refresh(0);
	output_enable = 0;
	alarm(0);
	getch();
	endwin();
#endif
}
